今日的程式碼 => GitHub
大家應該都知道 Flutter 的跳頁都會分成 2 種方式
這邊我會簡單介紹一下這兩者的用法,想要分享一下,我習慣用的方法,和資料夾的架構。
Navigator.push(context, MaterialPageRoute(builder: (context)=> new Page1())),
Navigator.of(context, rootNavigator: false).push(MaterialPageRoute(builder: (context) => new Page1())),
rootNavigator
非必填,預設為 false
,代表他會去找距離你最近節點的 Navigator
。如果 rootNavigator = true
,他則會去找 App 一打開,第一個碰到的 Navigator
。當作換頁的根據,也就是 MaterialApp 裡面的路由控制器。如果這邊沒有聽懂的話,沒關係,之後會講 BottomNavigationBar,到時候會再次帶入這個觀念。
new MaterialApp(
home: new Screen1(),
routes: <String, WidgetBuilder> {
'page1': (BuildContext context) => new Page1(),
'page2' : (BuildContext context) => new Page2(),
},
)
Navigator.pushNamed(context, 'page2'),
Navigator.of(context,rootNavigator: false).pushNamed('page2'),
帶參數到下一個畫面
Navigator.pushNamed(context, RouteName.bbb, arguments: '注意,這邊只能傳一個參數,如果想要傳多個參數,請自己寫個物件包起來'),
@override
Widget build(BuildContext context) {
final String string =ModalRoute.of(context)!.settings.arguments as String;
return Text(string);
}
假設現在有個情境 A 畫面要跳到 B,在這邊我會寫成 A->B 的樣子。
沒有哪一種比較好,就是看習慣問題而已。It's up to you.
我自己是用 Named
的方式。(我覺得這樣比較好控制跳頁的動畫等等~~,我可以專門開一個頁面管理它)。
return MaterialApp(
// 告知我的路由器是哪個
onGenerateRoute: MyRouter.generateRoute,
// 告知 App 開啟後第一個畫面是什麼
initialRoute: RouteName.aaa
);
RouteName
是一個字串。MyRoute
會對應到畫面。class RouteName {
static const String aaa = 'aaa';
static const String bbb = 'bbb';
}
class MyRouter {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case RouteName.aaa:
return NoAnimRouteBuilder(new AAA());
case RouteName.bbb:
return NoAnimRouteBuilder(new BBB());
default:
return CupertinoPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text('No route defined for ${settings.name}'),
),
));
}
}
}
例:
Navigator.pushNamed(context, RouteName.aaa),
那這樣的話 MyRouter 的 settings.name 就會是 RouteName.aaa
Animation
的 Builder
,這邊可以客製化它。class NoAnimRouteBuilder extends PageRouteBuilder {
final Widget page;
NoAnimRouteBuilder(this.page)
: super(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionDuration: Duration(milliseconds: 0),
transitionsBuilder:
(context, animation, secondaryAnimation, child) => child);
}